using System;
using System.IO;
using System.Text;
using ICSharpCode.TextEditor.Formatting.TSqlFormatter.Interfaces;

namespace ICSharpCode.TextEditor.Formatting.TSqlFormatter.Tokenizers
{
    public class TSqlStandardTokenizer : ISqlTokenizer
    {
        public enum SqlTokenizationType
        {
            WhiteSpace,
            OtherNode,
            SingleLineComment,
            SingleLineCommentCStyle,
            BlockComment,
            String,
            NString,
            QuotedString,
            BracketQuotedName,
            OtherOperator,
            Number,
            BinaryValue,
            MonetaryValue,
            DecimalValue,
            FloatValue,
            PseudoName,
            SingleAsterisk,
            SingleDollar,
            SingleHyphen,
            SingleSlash,
            SingleN,
            SingleLT,
            SingleGT,
            SingleExclamation,
            SinglePeriod,
            SingleZero,
            SinglePipe,
            SingleEquals,
            SingleOtherCompoundableOperator
        }

        public ITokenList TokenizeSQL(string inputSQL)
        {
            TokenList tokenList = new TokenList();
            StringReader stringReader = new StringReader(inputSQL);
            StringBuilder stringBuilder = new StringBuilder();
            SqlTokenizationType? currentTokenizationType = null;
            stringBuilder.Length = 0;
            int num = 0;
            for (int num2 = stringReader.Read(); num2 >= 0; num2 = stringReader.Read())
            {
                char c = (char)num2;
                if (!currentTokenizationType.HasValue)
                {
                    ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                }
                else
                {
                    switch (currentTokenizationType.Value)
                    {
                        case SqlTokenizationType.WhiteSpace:
                            if (IsWhitespace(c))
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            break;
                        case SqlTokenizationType.SinglePeriod:
                            if (c >= '0' && c <= '9')
                            {
                                currentTokenizationType = SqlTokenizationType.DecimalValue;
                                stringBuilder.Append('.');
                                stringBuilder.Append(c);
                            }
                            else
                            {
                                stringBuilder.Append('.');
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleZero:
                            if (c == 'x' || c == 'X')
                            {
                                currentTokenizationType = SqlTokenizationType.BinaryValue;
                                stringBuilder.Append('0');
                                stringBuilder.Append(c);
                            }
                            else if (c >= '0' && c <= '9')
                            {
                                currentTokenizationType = SqlTokenizationType.Number;
                                stringBuilder.Append('0');
                                stringBuilder.Append(c);
                            }
                            else if (c == '.')
                            {
                                currentTokenizationType = SqlTokenizationType.DecimalValue;
                                stringBuilder.Append('0');
                                stringBuilder.Append(c);
                            }
                            else
                            {
                                stringBuilder.Append('0');
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.Number:
                            if (c == 'e' || c == 'E')
                            {
                                currentTokenizationType = SqlTokenizationType.FloatValue;
                                stringBuilder.Append(c);
                            }
                            else if (c == '.')
                            {
                                currentTokenizationType = SqlTokenizationType.DecimalValue;
                                stringBuilder.Append(c);
                            }
                            else if (c >= '0' && c <= '9')
                            {
                                stringBuilder.Append(c);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.DecimalValue:
                            if (c == 'e' || c == 'E')
                            {
                                currentTokenizationType = SqlTokenizationType.FloatValue;
                                stringBuilder.Append(c);
                            }
                            else if (c >= '0' && c <= '9')
                            {
                                stringBuilder.Append(c);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.FloatValue:
                            if (c >= '0' && c <= '9')
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            if (c == '-' && stringBuilder.ToString().EndsWith("e", StringComparison.OrdinalIgnoreCase))
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            break;
                        case SqlTokenizationType.BinaryValue:
                            if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            break;
                        case SqlTokenizationType.SingleDollar:
                            stringBuilder.Append('$');
                            stringBuilder.Append(c);
                            currentTokenizationType = (((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) ? new SqlTokenizationType?(SqlTokenizationType.MonetaryValue) : new SqlTokenizationType?(SqlTokenizationType.PseudoName));
                            break;
                        case SqlTokenizationType.MonetaryValue:
                            if (c >= '0' && c <= '9')
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            if (c == '-' && stringBuilder.Length == 1)
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            if (c == '.' && !stringBuilder.ToString().Contains("."))
                            {
                                stringBuilder.Append(c);
                                break;
                            }
                            CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            break;
                        case SqlTokenizationType.SingleHyphen:
                            switch (c)
                            {
                                case '-':
                                    currentTokenizationType = SqlTokenizationType.SingleLineComment;
                                    break;
                                case '=':
                                    currentTokenizationType = SqlTokenizationType.OtherOperator;
                                    stringBuilder.Append('-');
                                    stringBuilder.Append(c);
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                    break;
                                default:
                                    currentTokenizationType = SqlTokenizationType.OtherOperator;
                                    stringBuilder.Append('-');
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                    ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                                    break;
                            }
                            break;
                        case SqlTokenizationType.SingleSlash:
                            switch (c)
                            {
                                case '*':
                                    currentTokenizationType = SqlTokenizationType.BlockComment;
                                    num++;
                                    break;
                                case '/':
                                    currentTokenizationType = SqlTokenizationType.SingleLineCommentCStyle;
                                    break;
                                case '=':
                                    currentTokenizationType = SqlTokenizationType.OtherOperator;
                                    stringBuilder.Append('/');
                                    stringBuilder.Append(c);
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                    break;
                                default:
                                    currentTokenizationType = SqlTokenizationType.OtherOperator;
                                    stringBuilder.Append('/');
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                    ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                                    break;
                            }
                            break;
                        case SqlTokenizationType.SingleLineComment:
                        case SqlTokenizationType.SingleLineCommentCStyle:
                            if (c == '\r' || c == '\n')
                            {
                                stringBuilder.Append(c);
                                int num3 = stringReader.Peek();
                                if (c == '\r' && num3 == 10)
                                {
                                    stringBuilder.Append((char)stringReader.Read());
                                }
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.BlockComment:
                            if (c == '*')
                            {
                                if (stringReader.Peek() == 47)
                                {
                                    num--;
                                    char value = (char)stringReader.Read();
                                    if (num > 0)
                                    {
                                        stringBuilder.Append(c);
                                        stringBuilder.Append(value);
                                    }
                                    else
                                    {
                                        CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                    }
                                }
                                else
                                {
                                    stringBuilder.Append(c);
                                }
                            }
                            else
                            {
                                stringBuilder.Append(c);
                                if (c == '/' && stringReader.Peek() == 42)
                                {
                                    stringBuilder.Append((char)stringReader.Read());
                                    num++;
                                }
                            }
                            break;
                        case SqlTokenizationType.OtherNode:
                        case SqlTokenizationType.PseudoName:
                            if (IsNonWordCharacter(c))
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            else
                            {
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.SingleN:
                            if (c == '\'')
                            {
                                currentTokenizationType = SqlTokenizationType.NString;
                            }
                            else if (IsNonWordCharacter(c))
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            else
                            {
                                currentTokenizationType = SqlTokenizationType.OtherNode;
                                stringBuilder.Append('N');
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.String:
                        case SqlTokenizationType.NString:
                            if (c == '\'')
                            {
                                if (stringReader.Peek() == 39)
                                {
                                    stringReader.Read();
                                    stringBuilder.Append(c);
                                }
                                else
                                {
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                }
                            }
                            else
                            {
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.QuotedString:
                            if (c == '"')
                            {
                                if (stringReader.Peek() == 34)
                                {
                                    stringReader.Read();
                                    stringBuilder.Append(c);
                                }
                                else
                                {
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                }
                            }
                            else
                            {
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.BracketQuotedName:
                            if (c == ']')
                            {
                                if (stringReader.Peek() == 93)
                                {
                                    stringReader.Read();
                                    stringBuilder.Append(c);
                                }
                                else
                                {
                                    CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                }
                            }
                            else
                            {
                                stringBuilder.Append(c);
                            }
                            break;
                        case SqlTokenizationType.SingleLT:
                            stringBuilder.Append('<');
                            currentTokenizationType = SqlTokenizationType.OtherOperator;
                            if (c == '=' || c == '>' || c == '<')
                            {
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleGT:
                            stringBuilder.Append('>');
                            currentTokenizationType = SqlTokenizationType.OtherOperator;
                            if (c == '=' || c == '>')
                            {
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleAsterisk:
                            stringBuilder.Append('*');
                            if (c == '=')
                            {
                                stringBuilder.Append(c);
                                currentTokenizationType = SqlTokenizationType.OtherOperator;
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleOtherCompoundableOperator:
                            currentTokenizationType = SqlTokenizationType.OtherOperator;
                            if (c == '=')
                            {
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SinglePipe:
                            currentTokenizationType = SqlTokenizationType.OtherOperator;
                            stringBuilder.Append('|');
                            if (c == '=' || c == '|')
                            {
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleEquals:
                            stringBuilder.Append('=');
                            if (c == '=')
                            {
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        case SqlTokenizationType.SingleExclamation:
                            stringBuilder.Append('!');
                            if (c == '=' || c == '<' || c == '>')
                            {
                                currentTokenizationType = SqlTokenizationType.OtherOperator;
                                stringBuilder.Append(c);
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                            }
                            else
                            {
                                currentTokenizationType = SqlTokenizationType.OtherNode;
                                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
                                ProcessOrOpenToken(ref currentTokenizationType, stringBuilder, c, tokenList);
                            }
                            break;
                        default:
                            throw new Exception("In-progress node unrecognized!");
                    }
                }
            }
            if (currentTokenizationType.HasValue)
            {
                if (currentTokenizationType.Value == SqlTokenizationType.BlockComment || currentTokenizationType.Value == SqlTokenizationType.String || currentTokenizationType.Value == SqlTokenizationType.NString || currentTokenizationType.Value == SqlTokenizationType.QuotedString || currentTokenizationType.Value == SqlTokenizationType.BracketQuotedName)
                {
                    tokenList.HasUnfinishedToken = true;
                }
                CompleteToken(ref currentTokenizationType, tokenList, stringBuilder);
            }
            return tokenList;
        }

        private static bool IsWhitespace(char targetCharacter)
        {
            return targetCharacter == ' ' || targetCharacter == '\t' || targetCharacter == '\n' || targetCharacter == '\r';
        }

        private static bool IsNonWordCharacter(char currentCharacter)
        {
            return IsWhitespace(currentCharacter) || IsOperatorCharacter(currentCharacter) || (IsCurrencyPrefix(currentCharacter) && currentCharacter != '$') || currentCharacter == '\'' || currentCharacter == '"' || currentCharacter == ',' || currentCharacter == '.' || currentCharacter == '[' || currentCharacter == '(' || currentCharacter == ')' || currentCharacter == '!' || currentCharacter == ';' || currentCharacter == ':';
        }

        private static bool IsCompoundableOperatorCharacter(char currentCharacter)
        {
            return currentCharacter == '/' || currentCharacter == '-' || currentCharacter == '+' || currentCharacter == '*' || currentCharacter == '%' || currentCharacter == '&' || currentCharacter == '^' || currentCharacter == '<' || currentCharacter == '>' || currentCharacter == '|';
        }

        private static bool IsOperatorCharacter(char currentCharacter)
        {
            return currentCharacter == '/' || currentCharacter == '-' || currentCharacter == '+' || currentCharacter == '%' || currentCharacter == '*' || currentCharacter == '&' || currentCharacter == '|' || currentCharacter == '^' || currentCharacter == '=' || currentCharacter == '<' || currentCharacter == '>' || currentCharacter == '~';
        }

        private static bool IsCurrencyPrefix(char currentCharacter)
        {
            return currentCharacter == '$' || currentCharacter == '¢' || currentCharacter == '£' || currentCharacter == '¤' || currentCharacter == '¥' || currentCharacter == '৲' || currentCharacter == '৳' || currentCharacter == '฿' || currentCharacter == '៛' || currentCharacter == '₠' || currentCharacter == '₡' || currentCharacter == '₢' || currentCharacter == '₣' || currentCharacter == '₤' || currentCharacter == '₥' || currentCharacter == '₦' || currentCharacter == '₧' || currentCharacter == '₨' || currentCharacter == '₩' || currentCharacter == '₪' || currentCharacter == '₫' || currentCharacter == '€' || currentCharacter == '₭' || currentCharacter == '₮' || currentCharacter == '₯' || currentCharacter == '₰' || currentCharacter == '₱' || currentCharacter == '﷼' || currentCharacter == '﹩' || currentCharacter == '＄' || currentCharacter == '￠' || currentCharacter == '￡' || currentCharacter == '￥' || currentCharacter == '￦';
        }

        private static void ProcessOrOpenToken(ref SqlTokenizationType? currentTokenizationType, StringBuilder currentNodeValue, char currentCharacter, ITokenList tokenContainer)
        {
            if (currentTokenizationType.HasValue)
            {
                throw new Exception("Cannot start a new Token: existing Tokenization Type is not null");
            }
            currentNodeValue.Length = 0;
            if (IsWhitespace(currentCharacter))
            {
                currentTokenizationType = SqlTokenizationType.WhiteSpace;
                currentNodeValue.Append(currentCharacter);
                return;
            }
            if (currentCharacter == '-')
            {
                currentTokenizationType = SqlTokenizationType.SingleHyphen;
                return;
            }
            if (currentCharacter == '$')
            {
                currentTokenizationType = SqlTokenizationType.SingleDollar;
                return;
            }
            if (currentCharacter == '/')
            {
                currentTokenizationType = SqlTokenizationType.SingleSlash;
                return;
            }
            if (currentCharacter == 'N')
            {
                currentTokenizationType = SqlTokenizationType.SingleN;
                return;
            }
            if (currentCharacter == '\'')
            {
                currentTokenizationType = SqlTokenizationType.String;
                return;
            }
            if (currentCharacter == '"')
            {
                currentTokenizationType = SqlTokenizationType.QuotedString;
                return;
            }
            if (currentCharacter == '[')
            {
                currentTokenizationType = SqlTokenizationType.BracketQuotedName;
                return;
            }
            if (currentCharacter == '(')
            {
                tokenContainer.Add(new Token(SqlTokenType.OpenParens, currentCharacter.ToString()));
                return;
            }
            if (currentCharacter == ')')
            {
                tokenContainer.Add(new Token(SqlTokenType.CloseParens, currentCharacter.ToString()));
                return;
            }
            if (currentCharacter == ',')
            {
                tokenContainer.Add(new Token(SqlTokenType.Comma, currentCharacter.ToString()));
                return;
            }
            if (currentCharacter == '.')
            {
                currentTokenizationType = SqlTokenizationType.SinglePeriod;
                return;
            }
            if (currentCharacter == '0')
            {
                currentTokenizationType = SqlTokenizationType.SingleZero;
                return;
            }
            if (currentCharacter >= '1' && currentCharacter <= '9')
            {
                currentTokenizationType = SqlTokenizationType.Number;
                currentNodeValue.Append(currentCharacter);
                return;
            }
            if (IsCurrencyPrefix(currentCharacter))
            {
                currentTokenizationType = SqlTokenizationType.MonetaryValue;
                currentNodeValue.Append(currentCharacter);
                return;
            }
            switch (currentCharacter)
            {
                case ';':
                    tokenContainer.Add(new Token(SqlTokenType.Semicolon, currentCharacter.ToString()));
                    return;
                case ':':
                    tokenContainer.Add(new Token(SqlTokenType.Colon, currentCharacter.ToString()));
                    return;
                case '*':
                    currentTokenizationType = SqlTokenizationType.SingleAsterisk;
                    return;
                case '=':
                    currentTokenizationType = SqlTokenizationType.SingleEquals;
                    return;
                case '<':
                    currentTokenizationType = SqlTokenizationType.SingleLT;
                    return;
                case '>':
                    currentTokenizationType = SqlTokenizationType.SingleGT;
                    return;
                case '!':
                    currentTokenizationType = SqlTokenizationType.SingleExclamation;
                    return;
                case '|':
                    currentTokenizationType = SqlTokenizationType.SinglePipe;
                    return;
            }
            if (IsCompoundableOperatorCharacter(currentCharacter))
            {
                currentTokenizationType = SqlTokenizationType.SingleOtherCompoundableOperator;
                currentNodeValue.Append(currentCharacter);
            }
            else if (IsOperatorCharacter(currentCharacter))
            {
                tokenContainer.Add(new Token(SqlTokenType.OtherOperator, currentCharacter.ToString()));
            }
            else
            {
                currentTokenizationType = SqlTokenizationType.OtherNode;
                currentNodeValue.Append(currentCharacter);
            }
        }

        private static void CompleteToken(ref SqlTokenizationType? currentTokenizationType, ITokenList tokenContainer, StringBuilder currentValue)
        {
            if (!currentTokenizationType.HasValue)
            {
                throw new Exception("Cannot complete Token, as there is no current Tokenization Type");
            }
            switch (currentTokenizationType)
            {
                case SqlTokenizationType.BlockComment:
                    tokenContainer.Add(new Token(SqlTokenType.MultiLineComment, currentValue.ToString()));
                    break;
                case SqlTokenizationType.OtherNode:
                    tokenContainer.Add(new Token(SqlTokenType.OtherNode, currentValue.ToString()));
                    break;
                case SqlTokenizationType.PseudoName:
                    tokenContainer.Add(new Token(SqlTokenType.PseudoName, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleLineComment:
                    tokenContainer.Add(new Token(SqlTokenType.SingleLineComment, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleLineCommentCStyle:
                    tokenContainer.Add(new Token(SqlTokenType.SingleLineCommentCStyle, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleHyphen:
                    tokenContainer.Add(new Token(SqlTokenType.OtherOperator, "-"));
                    break;
                case SqlTokenizationType.SingleDollar:
                    tokenContainer.Add(new Token(SqlTokenType.MonetaryValue, "$"));
                    break;
                case SqlTokenizationType.SingleSlash:
                    tokenContainer.Add(new Token(SqlTokenType.OtherOperator, "/"));
                    break;
                case SqlTokenizationType.WhiteSpace:
                    tokenContainer.Add(new Token(SqlTokenType.WhiteSpace, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleN:
                    tokenContainer.Add(new Token(SqlTokenType.OtherNode, "N"));
                    break;
                case SqlTokenizationType.SingleExclamation:
                    tokenContainer.Add(new Token(SqlTokenType.OtherNode, "!"));
                    break;
                case SqlTokenizationType.SinglePipe:
                    tokenContainer.Add(new Token(SqlTokenType.OtherNode, "|"));
                    break;
                case SqlTokenizationType.SingleGT:
                    tokenContainer.Add(new Token(SqlTokenType.OtherOperator, ">"));
                    break;
                case SqlTokenizationType.SingleLT:
                    tokenContainer.Add(new Token(SqlTokenType.OtherOperator, "<"));
                    break;
                case SqlTokenizationType.NString:
                    tokenContainer.Add(new Token(SqlTokenType.NationalString, currentValue.ToString()));
                    break;
                case SqlTokenizationType.String:
                    tokenContainer.Add(new Token(SqlTokenType.String, currentValue.ToString()));
                    break;
                case SqlTokenizationType.QuotedString:
                    tokenContainer.Add(new Token(SqlTokenType.QuotedString, currentValue.ToString()));
                    break;
                case SqlTokenizationType.BracketQuotedName:
                    tokenContainer.Add(new Token(SqlTokenType.BracketQuotedName, currentValue.ToString()));
                    break;
                case SqlTokenizationType.OtherOperator:
                case SqlTokenizationType.SingleOtherCompoundableOperator:
                    tokenContainer.Add(new Token(SqlTokenType.OtherOperator, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleZero:
                    tokenContainer.Add(new Token(SqlTokenType.Number, "0"));
                    break;
                case SqlTokenizationType.SinglePeriod:
                    tokenContainer.Add(new Token(SqlTokenType.Period, "."));
                    break;
                case SqlTokenizationType.SingleAsterisk:
                    tokenContainer.Add(new Token(SqlTokenType.Asterisk, currentValue.ToString()));
                    break;
                case SqlTokenizationType.SingleEquals:
                    tokenContainer.Add(new Token(SqlTokenType.EqualsSign, currentValue.ToString()));
                    break;
                case SqlTokenizationType.Number:
                case SqlTokenizationType.DecimalValue:
                case SqlTokenizationType.FloatValue:
                    tokenContainer.Add(new Token(SqlTokenType.Number, currentValue.ToString()));
                    break;
                case SqlTokenizationType.BinaryValue:
                    tokenContainer.Add(new Token(SqlTokenType.BinaryValue, currentValue.ToString()));
                    break;
                case SqlTokenizationType.MonetaryValue:
                    tokenContainer.Add(new Token(SqlTokenType.MonetaryValue, currentValue.ToString()));
                    break;
                default:
                    throw new Exception("Unrecognized SQL Node Type");
            }
            currentTokenizationType = null;
        }
    }
}
